package concurrent;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName DelayQueueExample
 * @Description DelayQueueExample
 * @Author wanghaiwei
 * @Date 2022/2/23 11:11
 */
public class DelayQueueExample {
    public static class DelayTask implements Delayed{
        private final long scheduleTime;
        private final String taskName;

        public DelayTask(long scheduleTime, String taskName) {
            this.scheduleTime = scheduleTime;
            this.taskName = taskName;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            long miliSec = scheduleTime - System.currentTimeMillis();
            return unit.convert(miliSec, TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(Delayed o) {
            return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
        }

        @Override
        public String toString() {
            return "延迟任务:" + taskName + ",延迟时间:" + scheduleTime;
        }
    }

    public static class DelayTaskConsumer implements Runnable {

        private final DelayQueue<DelayTask> delayQueue;

        public DelayTaskConsumer(DelayQueue<DelayTask> delayQueue) {
            this.delayQueue = delayQueue;
        }

        @Override
        public void run() {
            DelayTask task;
            try {
                while (true) {
                    task = delayQueue.take();
                    System.out.println(task);
                }
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread() + "结束");
            }
        }
    }

    public static void main(String[] args) {
        DelayQueue<DelayTask> delayQueue = new DelayQueue<>();
        for (int i = 0; i < 10; i++) {
            delayQueue.add(new DelayTask(i * 10 + System.currentTimeMillis(), "任务" + (i+1)));
        }
        Thread a = new Thread(new DelayTaskConsumer(delayQueue));
        Thread b = new Thread(new DelayTaskConsumer(delayQueue));
        a.start();
        b.start();
        while (true) {
            if (delayQueue.size() == 0) {
                a.interrupt();
                b.interrupt();
                return;
            }
        }
    }

}
